package com.moss.cloud.common.security.config;

import com.alibaba.ttl.threadpool.TtlExecutors;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 、
 * 线程池配置
 *
 * @author 瑾年
 * @date 2024年10月3日
 */
@Slf4j
@Configuration
@EnableAsync
public class ExecutorConfig {
    //配置队列大小
    private static final int queueCapacity = 100;
    //配置线程池中的线程的名称前缀
    private static final String namePrefix = "MOSS-ASYNC";
    //线程池维护线程所允许的空闲时间
    private static final int keepAliveSeconds = 60;
    //超時關閉時間
    private static final int awaitTerminationSeconds = 60;

    @Bean(name = "asyncServiceExecutor")
    public Executor asyncServiceExecutor() {
        log.info("初始化异步线程池");
        // 获取CPU核心数
        int cpuCores = Runtime.getRuntime().availableProcessors();
        int corePoolSize = cpuCores * 2;
        int maxPoolSize = cpuCores * 4;  // 最大线程数设置为核心线程数的2倍
        log.info("线程池配置：核心线程数:{}, 最大线程数:{}, 队列容量:{}",
                corePoolSize, maxPoolSize, queueCapacity);
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setThreadNamePrefix(namePrefix);
        executor.setKeepAliveSeconds(keepAliveSeconds);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(awaitTerminationSeconds);

        // 自定义线程工厂
        executor.setThreadFactory(new ThreadFactory() {
            private final AtomicInteger threadNumber = new AtomicInteger(1);
            @Override
            public Thread newThread(@NotNull Runnable r) {
                Thread thread = new Thread(r);
                thread.setName(namePrefix + "-" + threadNumber.getAndIncrement());
                if (thread.isDaemon()) {
                    thread.setDaemon(false);
                }
                if (thread.getPriority() != Thread.NORM_PRIORITY) {
                    thread.setPriority(Thread.NORM_PRIORITY);
                }
                return thread;
            }
        });

        // 添加线程池监控
        executor.setThreadNamePrefix(namePrefix);
        executor.setRejectedExecutionHandler((r, executor1) -> {
            log.warn("线程池已满，任务使用调用者线程执行");
            if (!executor1.isShutdown()) {
                r.run();
            }
        });
        executor.initialize();
        return TtlExecutors.getTtlExecutor(executor);
    }
}

